// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "DBManager/Service/Result/Summary/EIGENVALUE_CPLXService.h"

#include "Utility/Logging/SGLogger.h"

#include "DBManager/IService/Input/Subcase/ISubcaseService.h"
#include "DBManager/IService/Result/IResultDomainsService.h"
using namespace SG::DBManager;

// 注册服务
SERVICE_REG_WITH_DBM_IMPL (EIGENVALUE_CPLXService, IEIGENVALUE_CPLXRepository)

EIGENVALUE_CPLXService::EIGENVALUE_CPLXService (DBServiceFactory* const dbServiceFactory, IEIGENVALUE_CPLXRepository& repos)
    : m_repository (repos), m_dbServiceFactory (dbServiceFactory)
{}

EIGENVALUE_CPLXService::~EIGENVALUE_CPLXService () = default;
SG::DataStructure::Common::Status EIGENVALUE_CPLXService::Add (SG::DataStructure::Post::EIGENVALUE_CPLXData& data)
{
    auto domainService = m_dbServiceFactory->get<IResultDomainsService> ();

    // 1. 查询domainId
    SG::DBManager::Post::DomainRequest request (0, 0);

    SG::DataStructure::Common::Id domainId;  // 结果
    if (domainService->GetDomainId (request, domainId) == SG::DataStructure::Common::Status::STATUS_Failure)
    {
        return SG::DataStructure::Common::Status::STATUS_Failure;
    }

    // 2. 数据组装
    data.m_domainId = domainId;

    // 3. 添加结果
    std::vector<SG::DataStructure::Post::EIGENVALUE_CPLXData> list{ data };
    return m_repository.Add (domainId, list);
}

SG::DataStructure::Common::Status EIGENVALUE_CPLXService::Find (SG::DataStructure::Common::I64 subcaseId,
                                                                SG::DataStructure::Common::I64 mode,
                                                                _OUT SG::DataStructure::Post::EIGENVALUE_CPLXData& data)
{
    auto domainService = m_dbServiceFactory->get<IResultDomainsService> ();

    // 1. 查询domainId
    SG::DBManager::Post::DomainRequest request (0, 0);

    SG::DataStructure::Post::ResultDomains domain;

    if (domainService->Find (request, _OUT domain) == SG::DataStructure::Common::Status::STATUS_Failure)
    {
        return SG::DataStructure::Common::Status::STATUS_Failure;
    }

    // 2. 获取结果
    std::vector<SG::DataStructure::Post::EIGENVALUE_CPLXData> listData;
    if (m_repository.Find (domain.m_id, mode, listData) == SG::DataStructure::Common::Status::STATUS_Failure || listData.size () == 0)
    {
        return SG::DataStructure::Common::Status::STATUS_Failure;
    }

    // 3. 获取对应subcase Index的数据
    auto domains = domainService->GetAllData ();
    if (domains.size () == 0)
        return SG::DataStructure::Common::Status::STATUS_Failure;

    std::set<SG::DataStructure::Common::Id> subcaseIds;

    for (auto&& domain : domains)
    {
        // TODO(wuxingchuang) 并不是所有的subcase都有特征值
        if (domain.m_TimeFrequencyEigr != 0 && domain.m_Mode != 0
            && (domain.m_Analysis == SG::DataStructure::Post::AnalysisType::ANALYSISTYPE_Modes
                || domain.m_Analysis == SG::DataStructure::Post::AnalysisType::ANALYSISTYPE_Buckl))
            subcaseIds.insert (domain.m_Subcase);
    }

    const std::size_t index = std::distance (subcaseIds.begin (), subcaseIds.find (subcaseId));

    if (index >= listData.size ())
        return SG::DataStructure::Common::Status::STATUS_Failure;

    data = listData[index];

    return SG::DataStructure::Common::Status::STATUS_Success;
}
